package org.pp.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.pp.annotations.Permission;
import org.pp.core.AdminConstants;
import org.pp.core.AdminSessionUtil;
import org.pp.core.BizErro;
import org.pp.core.MiniappConstants;
import org.pp.entity.SysUser;
import org.pp.service.ISysMenuService;
import org.pp.service.ISysRoleMenuService;
import org.pp.service.ISysUserRoleService;
import org.pp.service.ISysUserService;
import org.pp.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Objects;
import java.util.Set;

@Aspect
@Component
@Slf4j
public class AdminPermissionAspect {

    @Autowired
    ISysUserRoleService userRoleService;

    @Autowired
    ISysRoleMenuService roleMenuService;

    @Autowired
    ISysMenuService menuService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    ISysUserService userService;

    @Before("@annotation(permission)")
    public void checkPermission(JoinPoint joinPoint, Permission permission) {
        //当前访问的接口需要拥有的权限值
        String value = permission.value();
        //具体逻辑
        Long userId = AdminSessionUtil.getUserId();
        //配置可跳过角色校验的权限
        if(Objects.nonNull(AdminConstants.permissionNocheckRole)&&
                redisUtil.isMember(AdminConstants.loginUserRoles + ":" + userId,AdminConstants.permissionNocheckRole)){
            return;
        }
        Set<Object> roleIds = redisUtil.getMembers(AdminConstants.loginUserRoles + ":" + userId);
        for (Object roleId : roleIds) {
            if (redisUtil.isMember(AdminConstants.roleAuths + ":" + roleId, value)) {
                return;
            }
        }
        throw BizErro.FORBID.erro();
    }

    @Before("execution (* org.pp.controller..*.*(..)) " +
            "&& !execution(* org.pp.controller.SysLoginController.getCode(..) )" +
            "&& !execution(* org.pp.controller.SysLoginController.login(..) )")
    public void checkLogin(JoinPoint joinPoint) {
        //具体校验登录逻辑
        //具体逻辑
        Long userId = AdminSessionUtil.getUserId();

        if(Objects.isNull(userId)){
            throw BizErro.TOKEN_EXPIRE.erro();
        }
        //检验用户是否已经退出登录
        if (!redisUtil.exists(AdminSessionUtil.getLoginUserNameKey(userId))) {
            throw BizErro.TOKEN_EXPIRE.erro();
        }

        SysUser user = userService.getById(userId);
        if(Objects.isNull(user)||!Objects.equals(user.getStatus(), AdminConstants.statusActive)){
            throw BizErro.TOKEN_EXPIRE.erro();
        }
    }

}
